package cn.pconline.security2.authentication;

import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HostConfiguration;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

import java.net.SocketTimeoutException;
import java.io.BufferedReader;
import java.io.InputStreamReader;

import cn.pconline.security2.authentication.ssl.EasySSLProtocolSocketFactory;

/**
 * Copyrights 2005, Guangzhou Intellisoft ltd.
 * User: chen xiaohu
 * Date: 2005-12-9
 * Time: 14:42:09
 */
public class HttpInvoker {
    private static final Log LOG = LogFactory.getLog(HttpInvoker.class);

    private int timeout = 10000;
    private boolean useProxy;
    private String proxyUrl;
    private int proxyPort;
    private String proxyUser;
    private String proxyPassword;
    private boolean useSSL;
    private int sslPort;

    public void setUseSSL(boolean userSSL) {
        this.useSSL = userSSL;
    }

    public void setSslPort(int sslPort) {
        this.sslPort = sslPort;
    }

    public void setTimeout(int timeout) {
        this.timeout = timeout;
    }

    public void setUseProxy(boolean useProxy) {
        this.useProxy = useProxy;
    }

    public void setProxyUrl(String proxyUrl) {
        this.proxyUrl = proxyUrl;
    }

    public void setProxyPort(int proxyPort) {
        this.proxyPort = proxyPort;
    }

    public void setProxyUser(String proxyUser) {
        this.proxyUser = proxyUser;
    }

    public void setProxyPassword(String password) {
        this.proxyPassword = password;
    }

    /**
     * 初始化，必须执行
     */
    public void init() {
    }

    private HttpClient getClient() {
        HttpClient httpClient = new HttpClient();
        httpClient.getParams().setParameter("http.protocol.content-charset", "gbk");
        httpClient.getParams().setSoTimeout(timeout);

        if (useSSL) {
            if (sslPort > 0) {
                Protocol myhttps = new Protocol("https",
                        (ProtocolSocketFactory)new EasySSLProtocolSocketFactory(), sslPort);
                Protocol.registerProtocol("https", myhttps);
            }
        }

        if (useProxy) {
            HostConfiguration hc = new HostConfiguration();
            hc.setProxy(proxyUrl, proxyPort);
            httpClient.setHostConfiguration(hc);
            if (proxyUser != null) {
                httpClient.getState().setProxyCredentials(
                        AuthScope.ANY,
                        new UsernamePasswordCredentials(proxyUser, proxyPassword)
                );
            }
        }

        return httpClient;
    }

    /**
     * 执行http get请求
     * @param url
     * @return HttpResult
     */
    public HttpResult invoke(String url) {
        GetMethod get = null;
        HttpResult result = null;
        try {
            get = new GetMethod(url);
            getClient().executeMethod(get);
            int statusCode = get.getStatusCode();
            String statusText = get.getStatusText();
            result = new HttpResult(statusCode, statusText);

            if (statusCode == 200) {
                StringBuffer buf = new StringBuffer();
                BufferedReader br = new BufferedReader(new InputStreamReader(get.getResponseBodyAsStream()));
                String line;
                while ((line = br.readLine()) != null) {
                    buf.append(line).append('\n');
                }
                result.setBody(buf.toString());
            }

        } catch (SocketTimeoutException e) {
            result = new HttpResult(408, "REQUEST TIMEOUT. " + e.getMessage());
        } catch (java.net.ConnectException e) {
            result = new HttpResult(321, "Connection refused. " + e.getMessage());
        } catch (Exception e) {
            LOG.error(e);
            result = new HttpResult(123, e.getMessage());
        } finally {
            if (get != null) {
                try {
                    //byte[] bytes = get.getResponseBody();
                    get.releaseConnection();
                } catch (Exception e) {
                    LOG.error(e);
                }
            }
        }

        return result;
    }

    /**
     * HTTP请求结果
     */
    public static class HttpResult {
        int statusCode;
        String statusText;
        String body;

        public HttpResult() {
        }

        public HttpResult(int code, String text) {
            this.statusCode = code;
            this.statusText = text;
        }

        public int getStatusCode() {
            return statusCode;
        }

        public void setStatusCode(int statusCode) {
            this.statusCode = statusCode;
        }

        public String getStatusText() {
            return statusText;
        }

        public void setStatusText(String statusText) {
            this.statusText = statusText;
        }

        public String getBody() {
            return body;
        }

        public void setBody(String body) {
            this.body = body;
        }

        public String toString() {
            StringBuffer buf = new StringBuffer();
            buf.append(statusCode);
            buf.append("#");
            buf.append(statusText);
            return buf.toString();
        }
    }

}
